#ifndef _MESSAGEQUEUEMANAGER_H_
#define _MESSAGEQUEUEMANAGER_H_

#include <string>
#include <list>

namespace rise
{
namespace threading
{
  class CCriticalSection;
}
}

namespace smq
{
  class MessageQueue;
  struct Message;

  typedef std::list<std::string> StringList; //!< string list

  //! queue watcher
  struct QueueWatcher
  {
    virtual ~QueueWatcher() {}

    //! notify operator
    /*! called when new message for this thread is arrived
      \param rMsg - new message to send
      */
    virtual void operator()(const Message& rMsg) = 0;
  };

  //! message queue manager
  class MessageQueueManager
  {
  public:
    //! get message queue manager instance
    /*! \return message queue manager instance
      */
    static MessageQueueManager& Inst();

    //! create queue
    /*! \param sQueueName - queue name
      */
    MessageQueue& CreateQueue(const std::string& sQueueName);

    //! remove queue
    /*! \param sQueueName - queue name
      */
    void RemoveQueue(const std::string& sQueueName);

    //! get queue
    /*! \param sQueueName - queue name
        \return queue
      */
    MessageQueue& GetQueue(const std::string& sQueueName);

    //! get queues list
    /*! \param rlsQueues - (out) queue list
      */
    void GetQueueList(StringList& rlsQueues);

    //! get queues list with filter
    /*! \param  sFilter - filter
        \param rlsQueues - (out) queue list
      */
    void GetFilteredQueueList(const std::string& sFilter, StringList& rlsQueues);

    //! add queue watcher
    /*! \param sQueueName - queue name
        \param pQueueWatcher - queue watcher
      */
    void AddQueueWatcher(const std::string& sQueueName, QueueWatcher* pQueueWatcher);

    //! remove queue watcher
    /*! \param sQueueName - queue name
        \param pQueueWatcher - queue watcher
      */
    void RemoveQueueWatcher(const std::string& sQueueName, QueueWatcher* pQueueWarcher);

    //! remove queue watcher from all queues
    /*! \param pQueueWatcher - queue watcher
      */
    void RemoveQueueWatcher(QueueWatcher* pQueueWarcher);

    //! add message into queues and send to subscribers
    /*! \param rMsg - message
      */
    void AddMessage(Message& rMsg);

    //! set default queue limit
    /*! \param  nLimit - queue limit
    */
    void SetDefaultQueueLimit(int nLimit = 100);

    //! get lock
    rise::threading::CCriticalSection& GetLock();

  protected:
    MessageQueueManager();
    ~MessageQueueManager();

  private:
    static MessageQueueManager* m_pInst;
    struct MessageQueueManagerImpl;
    MessageQueueManagerImpl* m_pImpl;
  };
}

#endif // _MESSAGEQUEUEMANAGER_H_
